# -*- coding: UTF-8 -*-
import requests
import json
import uuid
from flask import current_app
from PIL import Image
from StringIO import StringIO


# 1.本地URL调试
# 2.豆瓣上线
# 3.把URL换成config

__all__ = ['QQClient']


def _build_uri(base_uri, params):
    if not base_uri.startswith("https://"):
        raise ValueError('Protocol must be HTTPS, invalid URL: %s' % base_uri)
    if not isinstance(params, dict):
        raise ValueError('Params must be a dict type!')
    args = []
    for (k, v) in params.iteritems():
        args.append("%s=%s" % (k, v))
    return base_uri + '?' + '&'.join(args)


def _decode_querystring(qs):
    return dict([item.split('=', 1) for item in qs.split("&")])


class QQClient(object):
    QQ_CLIENT_ID = "101136286"
    QQ_CLIENT_SECRET = "2e0b1916e963328fe97d0142a1ba5d69"
    AUTHORIZATION_URI = "https://graph.qq.com/oauth2.0/authorize"
    TOKEN_URI = "https://graph.qq.com/oauth2.0/token"
    OPENID_URI = "https://graph.qq.com/oauth2.0/me"
    GET_UER_INFO_URI = "https://graph.qq.com/user/get_user_info"

    def __init__(self):
        config = current_app.config
        self.redirect_uri = config.get('SITE_DOMAIN') + '/account/qq_login'
        self.access_token = None
        self.openid = None

    def set_redirect_url(self, url='http://dxb.pypyhc.com/account/qq_login'):
        self.redirect_uri = url

    def get_qq_login_url(self):
        params = {
            'response_type': 'code',
            'client_id': QQClient.QQ_CLIENT_ID,
            'redirect_uri': self.redirect_uri,
            'scope': 'get_user_info'
        }
        return _build_uri(QQClient.AUTHORIZATION_URI, params)

    def _get_access_token(self, code):
        """
        token_access接口返回值:
        access_token=0E547F55C1BB544E0D9C7161BA8615C3&expires_in=7776000&refresh_token
        =9BDF5EFCE3D70BDCCE0E773295237A45
        """
        data = {
            'grant_type': 'authorization_code',
            'client_id': QQClient.QQ_CLIENT_ID,
            'client_secret': QQClient.QQ_CLIENT_SECRET,
            'code': code,
            'redirect_uri': self.redirect_uri
        }
        res = requests.get(QQClient.TOKEN_URI, params=data, verify=True).text
        # body = res.replace('callback','').replace('(','').replace(')','').replace(';',
        # '').replace('\n','')
        try:
            body = dict([item.split('=', 1) for item in res.split("&")])
            self.access_token = body["access_token"]
        except Exception, e:
            print e.args, e.message
            self.access_token = None

    def _get_open_id(self):
        """
        openid接口返回:
        callback( {"client_id":"101080468","openid":"1DC858D0AED1541CDE2D7CEA679F08C4"} );
        """
        if self.access_token is None:
            raise ValueError("Failed to get access_token!!!")

        res = requests.get(QQClient.OPENID_URI, params={"access_token": self.access_token}).text
        if res.startswith("callback"):
            p1 = res.find("{")
            p2 = res.find("}") + 1
            body = res[p1:p2]
        else:
            body = None
        try:
            # body = eval(body)
            body = json.loads(body)
            self.openid = body['openid']
        except Exception, e:
            print e.args
            self.openid = None

    def get_user_info(self, code):
        self._get_access_token(code)
        self._get_open_id()
        if self.openid is None:
            raise ValueError("Failed to get openid!!!")

        data = {
            'access_token': self.access_token,
            'openid': self.openid,
            'oauth_consumer_key': self.QQ_CLIENT_ID
        }
        user_info = {}
        error = None
        try:
            res = requests.get(QQClient.GET_UER_INFO_URI, params=data).json()
            user_info['user_id'] = self.openid
            user_info['user_name'] = res['nickname']
            user_info['avatar'] = res['figureurl_2']
            user_info['desc'] = ''
            return user_info, error
        except Exception, e:
            # print e.args, e.message
            error = (e.args, e.message)
            return user_info, error


def GetUriList():
    """
    伪单例模式，只初始化一次url
    """
    if not GetUriList.__dict__.has_key('urilist'):
        # print "init GetUriList"
        qq = QQClient()

        urilist = {}
        urilist['qq_url'] = qq.get_qq_login_url()

        GetUriList.urilist = urilist
    return GetUriList.urilist


class OpenID_Type(object):
    Douban = 0
    Sina = 1
    QQ = 2
    RenRen = 3
    Winxin = 4


def BindUser(user, openid, idtype):
    """
    给用户添加新的openid
    """
    oid = OpenID.query.filter(OpenID.user_id == user.id).first()
    if oid:
        types = [oid.Douban_id, oid.Sina_id, oid.QQ_id, oid.Renren_id, oid.Winxin_id]
        types[int(idtype)] = openid
        oid.QQ_id = types[2]
        db.session.add(oid)
        db.session.commit()
    else:
        CreateUser(user, openid, idtype)


def CreateUser(user, oid, idtype):
    """
    将用户id绑定到openid表
    Douban = 0
    Sina = 1
    QQ = 2
    RenRen = 3
    Winxin =4
    """
    types = [None, None, None, None, None]
    types[int(idtype)] = str(oid)
    nid = OpenID(QQ_id=types[2])
    nid.user = user
    db.session.add(nid)
    db.session.commit()


def save_avatar(url):
    """
    保存图片，并将图片裁剪到200大小
    """
    config = current_app.config
    res = requests.get(url).content
    image = Image.open(StringIO(res))
    if image.mode != "RGB":
        image = image.convert("RGB")
    w, h = image.size
    if w > h:
        border = h
        avatar_crop_region = ((w - border) / 2, 0, (w + border) / 2, border)
    else:
        border = w
        avatar_crop_region = (0, (h - border) / 2, border, (h + border) / 2)
    image = image.crop(avatar_crop_region)
    # 缩放
    max_border = 200
    if border > max_border:
        image = image.resize((max_border, max_border), Image.ANTIALIAS)
    file_name = str(uuid.uuid4()) + '.jpg'
    image.save(config.get('UPLOADS_DEFAULT_DEST') + '/avatars/' + file_name)
    return file_name
